package org.minbox.framework.mantool.core.support.instance;

import org.minbox.framework.mantool.core.exception.MantoolException;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class InstanceFactory implements Instance {

    /**
     * 单例 Map 对象
     * */
    private final Map<String,Object> singletonMap = new ConcurrentHashMap<>();

    /**
     * 线程内 Map 对象
     * */
    private ThreadLocal<Map<String, Object>> mapThreadLocal = new ThreadLocal<>();

    @Override
    public <T> T singleton(Class<T> tClass) {
        final String key = tClass.getName();
        T instance = (T) singletonMap.get(key);
        if(instance==null){
            instance = this.multiple(tClass);
            singletonMap.put(key,instance);
        }
        return instance;
    }

    @Override
    public <T> T multiple(Class<T> tClass) {
        try {
            return tClass.newInstance();
        } catch (InstantiationException | IllegalAccessException e){
            throw new MantoolException(e);
        }
    }

    @Override
    public <T> T threadLocal(Class<T> tClass) {
        Map<String,Object> map = mapThreadLocal.get();
        if(map==null){
            map = new ConcurrentHashMap<>();
        }
        T instance = this.multiple(tClass);
        map.put(tClass.getName(),instance);
        mapThreadLocal.set(map);
        return instance;
    }

    /**
     * 静态内部类单例实现
     * */
    private static class SingletonHolder {
        private static final InstanceFactory INSTANCE_FACTORY = new InstanceFactory();
    }

    /**
     * 获取当前类单例对象
     * */
    public static InstanceFactory getInstance() {
        return SingletonHolder.INSTANCE_FACTORY;
    }

    /**
     * 私有化构造方法
     * */
    private InstanceFactory(){ }
}
